package com.dataseek.iot.sys.manager.controller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dataseek.iot.core.constant.ResponseConst;
import com.dataseek.iot.core.base.IController;
import com.dataseek.iot.core.constant.SystemConst;
import com.dataseek.iot.core.jwt.JwtTokenProvider;
import com.dataseek.iot.core.request.QueryPage;
import com.dataseek.iot.core.request.QueryPage2;
import com.dataseek.iot.core.request.QueryParam;
import com.dataseek.iot.core.response.ResponseEntity;
import com.dataseek.iot.core.util.AuthUtil;
import com.dataseek.iot.core.util.ParseUtil;
import com.dataseek.iot.core.util.WrapperUtil;
import com.dataseek.iot.mysql.entity.Role;
import com.dataseek.iot.mysql.entity.User;
import com.dataseek.iot.mysql.service.impl.RoleServiceImpl;
import com.dataseek.iot.mysql.service.impl.UserServiceImpl;
import com.dataseek.iot.sys.manager.handler.UserServiceHandler;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author cc
 * @since 2021-09-05
 */
@RestController
@RequestMapping("/user")
@Api(tags = "用户接口")
@Slf4j
public class UserController implements IController<User> {

    @Autowired
    UserServiceHandler userService;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    JwtTokenProvider jwtTokenProvider;

    @Autowired
    UserServiceImpl userServiceImpl;

    @Autowired
    RoleServiceImpl roleService;

    @PutMapping("/addOne")
    @ApiOperation("保存单个用户")
    @Override
    public Mono<ResponseEntity> saveOne(@RequestBody User entity) {
        User user = entity;
        if(Objects.nonNull(user.getPassword())){
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        return userService.saveOne(user);
    }

    @PostMapping("/addBatch")
    @ApiOperation("批量保存用户数据")
    @Override
    public Mono<ResponseEntity> saveBatch(@RequestBody List<User> lists) {
        if(Objects.nonNull(lists)&&lists.size()>0){
            lists.forEach(user -> {
                if(Objects.nonNull(user.getPassword())){
                    user.setPassword(passwordEncoder.encode(user.getPassword()));
                }
                user.setPassword(passwordEncoder.encode(user.getPassword()));
                lists.add(user);
            });
        }
        return userService.saveBatch(lists);
    }


    @DeleteMapping("/{id}")
    @ApiOperation("根据ID移除用户信息")
    @Override
    public Mono<ResponseEntity> remove(@PathVariable String id) {
        return userService.remove(id);
    }

    @DeleteMapping("/removeByIds")
    @ApiOperation("根据ID批量移除用户信息")
    @Override
    public Mono<ResponseEntity> removeAll(@RequestBody List<String> ids) {
        return userService.removeAll(ids);
    }

    @DeleteMapping("/remove")
    @ApiOperation("根据条件移除用户信息")
    @Override
    public Mono<ResponseEntity> remove(@RequestBody List<QueryParam> params) {
        Wrapper wrapper = WrapperUtil.assembleParams(params);
        return userService.remove(wrapper);
    }

    @PostMapping("/updateOne")
    @ApiOperation("更新用户信息")
    @Override
    public Mono<ResponseEntity> updateOne(@RequestBody User entity) {
        return userService.updateOne(entity);
    }

    @PostMapping("/update")
    @ApiOperation("根据条件更新用户信息")
    @Override
    public Mono<ResponseEntity> update(@RequestBody List<QueryParam> params) {
        Wrapper wrapper = WrapperUtil.assembleParams(params);
        return userService.update(wrapper);
    }

    @PostMapping("/updatePassword")
    @ApiOperation("更新密码")
    public Mono<ResponseEntity> updatePassword(@RequestBody User user){
        if(Objects.nonNull(user.getPassword())){
            String password = passwordEncoder.encode(user.getPassword());
            Long id       = user.getUserInnerId();
            UpdateWrapper wrapper = new UpdateWrapper();
            wrapper.set("password", password);
            wrapper.eq("user_inner_id", id);
            return userService.update(wrapper);
        }
        ResponseEntity entity = new ResponseEntity();
        entity.setCode(ResponseConst.NULL_PARAM_CODE);
        entity.setMsg(ResponseConst.NULL_PARAM);
        entity.setData("");
        return Mono.just(entity);
    }

    @PostMapping("/updateBatch")
    @ApiOperation("批量更新")
    @Override
    public Mono<ResponseEntity> updateBatch(@RequestBody List<User> entities) {
        return userService.updateBatch(entities);
    }

    @PostMapping("/page/find")
    @ApiOperation("无条件分页查询")
//    @ApiImplicitParams(
//            @ApiImplicitParam(name = "page", value = "分页对象", required = true,
//            example = "{" +
//                    " //当前页面，默认1"+
//                    "  current: 0," +
//                    " //是否命中count缓存 默认为 false"+
//                    "  hitCount: true," +
//                    "//单页分页条数限制"+
//                    "  maxLimit: 4," +
//                    "  //排序字段设置"+
//                    "  orders: [" +
//                    "    {asc: true, column: username }" +
//                    "  ]," +
//                    "  searchCount: true," +
//                    " //每页条数"+
//                    "  size: 10,"+
//                    "}")
//    )
    @Override
    public Mono<ResponseEntity> page(@RequestBody Page p) {
        return userService.page(p);
    }

    @PostMapping("/page/findWithParam")
    @ApiOperation("分页查询，带查询条件")
    @Override
    public Mono<ResponseEntity> page(@RequestBody QueryPage queryPage) {
        if(queryPage==null||queryPage.getParams()==null||queryPage.getPage()==null){
            ResponseEntity entity  = new ResponseEntity();
            entity.setCode(ResponseConst.BAD_REQUEST_CODE);
            entity.setMsg(ResponseConst.BAD_REQUEST);
            return userService.defaultResponseOne(entity);
        }
        return userService.page(queryPage.getPage(), WrapperUtil.assembleParams(queryPage.getParams()));
    }

    /**
     * 根据IDS查询数据
     * @param ids
     * @return
     */
    @PostMapping("/findById")
    @ApiOperation("根据ID查询数据")
    @Override
    public Flux<ResponseEntity> findByIds(@RequestBody List<String> ids) {
        return userService.find(ids);
    }

    /**
     * 根据查询条件查询数据
     * @param params
     * @return
     */
    @PostMapping("/findByParams")
    @ApiOperation("根据查询条件查询参数")
    @Override
    public Flux<ResponseEntity> find(@RequestBody List<QueryParam> params){
        ResponseEntity entity = new ResponseEntity();
        if(params==null){
            entity.setCode(ResponseConst.BAD_REQUEST_CODE);
            entity.setMsg(ResponseConst.BAD_REQUEST);
            return userService.defaultResponseTwo(entity);
        }else if(params.size()==0){
            entity.setCode(ResponseConst.NULL_PARAM_CODE);
            entity.setMsg(ResponseConst.NULL_PARAM);
            return userService.defaultResponseTwo(entity);
        }
        return userService.find(WrapperUtil.assembleParams(params));
    }

    /**
     * 根据id条件查询数据
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @ApiOperation("根据ID查询用户")
    @Override
    public Mono<ResponseEntity> findOne(@PathVariable String id) {
        return userService.findOne(id);
    }

    /**
     * 查询所有数据
     * @return
     */
    @GetMapping("/findAll")
    @ApiOperation("查询所有")
    @Override
    public Flux<ResponseEntity> findAll() {
        return userService.findAll();
    }

    @PostMapping("/findByJSONParams")
    @ApiOperation("条件查询，没有分页")
    @Override
    public Flux<ResponseEntity> find(@RequestBody JSONObject json) {
        QueryWrapper wrapper = ParseUtil.parseJson(json);
        return userService.find(wrapper);
    }

    @PostMapping("/page/findByJSONParams")
    @ApiOperation("分页查询，传参为json")
    @Override
    public Mono<ResponseEntity> page(@RequestBody JSONObject json) {
        QueryPage2 queryPage2 = ParseUtil.parseJsonWithPage(json);
        QueryWrapper wrapper = queryPage2.getWrapper();

        return userService.page(queryPage2.getPage(),queryPage2.getWrapper());
    }

    @PostMapping("/page/ignoreSuperUser/findByJSONParams")
    @ApiOperation("分页查询，处理超级用户，传参为json")
    public Mono<ResponseEntity> pageIgnoreSuperUser(@RequestBody JSONObject json, ServerWebExchange exchange) {
        QueryPage2 queryPage2 = ParseUtil.parseJsonWithPage(json);
        QueryWrapper wrapper = queryPage2.getWrapper();
        String username = AuthUtil.getUsername(exchange, jwtTokenProvider);
        User user = userServiceImpl.findByUsername(username);
        Role role = roleService.getById(user.getRoleId());
        Role superRole = roleService.getRoleByCode(SystemConst.SUPER_USER);
        if(!role.getRoleCode().equals(SystemConst.SUPER_USER)){
            wrapper.or(true).notIn("role_id", superRole.getRoleInnerId());
        }
        return userService.page(queryPage2.getPage(),queryPage2.getWrapper());
    }
}
